﻿/*
* 创建者：LIYINFAI
* 创建时间：2023/10/15 11:40:00
* 描述：
* --------------------------------------
* 修改说明：
* --------------------------------------
*/
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace CommonLibrary
{
    /// <summary>
    /// 测试仪查询参数PLC地址
    /// </summary>
    public class RJ6902GXQueryParameterSetting
    {
        /// <summary>
        /// 配置文件
        /// </summary>
        private static string CONFIG_FILE_PATH = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "RJ6902GXQueryParameterSetting.json");
        /// <summary>
        /// 备注名称请与测试仪的一致
        /// </summary>
        [Description("备注")]
        [JsonProperty(PropertyName = "Remark")]
        public string Remark { get; set; } = string.Empty;
        /// <summary>
        /// 触发参数读取地址
        /// </summary>
        [Description("触发参数读取地址")]
        [JsonProperty(PropertyName = "TriggerAddress")]
        public string TriggerAddress { get; set; } = string.Empty;
        /// <summary>
        /// 编号地址
        /// </summary>
        [Description("编号地址")]
        [JsonProperty(PropertyName = "NoAddress")]
        public string NoAddress { get; set; } = string.Empty;
        /// <summary>
        /// 名称地址
        /// </summary>
        [Description("名称地址")]
        [JsonProperty(PropertyName = "NameAddress")]
        public string NameAddress { get; set; } = string.Empty;
        /// <summary>
        /// 电压设置值
        /// </summary>
        [Description("电压设置值")]
        [JsonProperty(PropertyName = "VoltageAddress")]
        public string VoltageAddress { get; set; } = string.Empty;
        /// <summary>
        /// TK地址
        /// </summary>
        [Description("TK地址")]
        [JsonProperty(PropertyName = "TKAddress")]
        public string TKAddress { get; set; } = string.Empty;
        /// <summary>
        /// TF地址
        /// </summary>
        [Description("TF地址")]
        [JsonProperty(PropertyName = "TFAddress")]
        public string TFAddress { get; set; } = string.Empty;
        /// <summary>
        /// Vd1设置值地址
        /// </summary>
        [Description("Vd1设置值地址")]
        [JsonProperty(PropertyName = "Vd1SettingAddress")]
        public string Vd1SettingAddress { get; set; } = string.Empty;
        /// <summary>
        /// Vd2设置值地址
        /// </summary>
        [Description("Vd2设置值地址")]
        [JsonProperty(PropertyName = "Vd2SettingAddress")]
        public string Vd2SettingAddress { get; set; } = string.Empty;
        /// <summary>
        /// Vd3设置值地址
        /// </summary>
        [Description("Vd3设置值地址")]
        [JsonProperty(PropertyName = "Vd3SettingAddress")]
        public string Vd3SettingAddress { get; set; } = string.Empty;
        /// <summary>
        /// TL设置值地址
        /// </summary>
        [Description("TL设置值地址")]
        [JsonProperty(PropertyName = "TLSettingAddress")]
        public string TLSettingAddress { get; set; } = string.Empty;
        /// <summary>
        /// TH设置值地址
        /// </summary>
        [Description("TH设置值地址")]
        [JsonProperty(PropertyName = "THSettingAddress")]
        public string THSettingAddress { get; set; } = string.Empty;
        /// <summary>
        /// 标准波形的电阻测试时间地址
        /// </summary>
        [Description("标准波形的电阻测试时间地址")]
        [JsonProperty(PropertyName = "ResistanceTimeAddress")]
        public string ResistanceTimeAddress { get; set; } = string.Empty;
        /// <summary>
        /// 标准波形的下限电阻地址
        /// </summary>
        [Description("标准波形的下限电阻地址")]
        [JsonProperty(PropertyName = "ResistanceLowerLimitAddress")]
        public string ResistanceLowerLimitAddress { get; set; } = string.Empty;
        /// <summary>
        /// Tscale地址
        /// </summary>
        [Description("Tscale地址")]
        [JsonProperty(PropertyName = "TscaleAddress")]
        public string TscaleAddress { get; set; } = string.Empty;
        /// <summary>
        /// Vd1值地址
        /// </summary>
        [Description("Vd1值地址")]
        [JsonProperty(PropertyName = "Vd1Address")]
        public string Vd1Address { get; set; } = string.Empty;
        /// <summary>
        /// Vd2值地址
        /// </summary>
        [Description("Vd2值地址")]
        [JsonProperty(PropertyName = "Vd2Address")]
        public string Vd2Address { get; set; } = string.Empty;
        /// <summary>
        /// Vd3值地址
        /// </summary>
        [Description("Vd3值地址")]
        [JsonProperty(PropertyName = "Vd3Address")]
        public string Vd3Address { get; set; } = string.Empty;
        /// <summary>
        /// Vp值地址
        /// </summary>
        [Description("Vp值地址")]
        [JsonProperty(PropertyName = "VpAddress")]
        public string VpAddress { get; set; } = string.Empty;
        /// <summary>
        /// TP值地址
        /// </summary>
        [Description("TP值地址")]
        [JsonProperty(PropertyName = "TPAddress")]
        public string TPAddress { get; set; } = string.Empty;
        /// <summary>
        /// 标准波形电阻值地址
        /// </summary>
        [Description("标准波形电阻值地址")]
        [JsonProperty(PropertyName = "ResistanceDataAddress")]
        public string ResistanceDataAddress { get; set; } = string.Empty;
        /// <summary>
        /// 获取配置信息
        /// </summary>
        /// <returns></returns>
        public static List<RJ6902GXQueryParameterSetting> GetQueryParameterSettings()
        {
            return CommonHelper.GetJsonListFromFile<RJ6902GXQueryParameterSetting>(CONFIG_FILE_PATH);
        }
        /// <summary>
        /// 保存配置信息
        /// </summary>
        /// <param name="settings"></param>
        public static void SaveQueryParameterSettings(List<RJ6902GXQueryParameterSetting> settings)
        {
            CommonHelper.SaveToJsonFile(settings, CONFIG_FILE_PATH);
        }
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// RJ6902GX配置信息
    /// </summary>
    public class RJ6902GXSetting
    {
        private static string CONFIG_FILE_PATH = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "RJ6902GXSetting.json");
        /// <summary>
        /// 编号
        /// </summary>
        [Description("编号")]
        [JsonProperty(PropertyName = "No")]
        public short No { get; set; } = 16;
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [JsonProperty(PropertyName = "Name")]
        public string Name { get; set; } = "ABCDEFGH";
        /// <summary>
        /// Vd1设定
        /// </summary>
        [Description("Vd1设定")]
        [JsonProperty(PropertyName = "Vd1")]
        public int Vd1 { get; set; } = 10;
        /// <summary>
        /// Vd2设定
        /// </summary>
        [Description("Vd2设定")]
        [JsonProperty(PropertyName = "Vd2")]
        public int Vd2 { get; set; } = 10;
        /// <summary>
        /// Vd3设定
        /// </summary>
        [Description("Vd3设定")]
        [JsonProperty(PropertyName = "Vd3")]
        public int Vd3 { get; set; } = 10;
        /// <summary>
        /// 充电电压
        /// </summary>
        [Description("充电电压")]
        [JsonProperty(PropertyName = "ChargeVoltage")]
        public short ChargeVoltage { get; set; } = 200;
        /// <summary>
        /// TK充电时间
        /// </summary>
        [Description("TK充电时间")]
        [JsonProperty(PropertyName = "TKTime")]
        public short TKTime { get; set; } = 100;
        /// <summary>
        /// TFTime
        /// </summary>
        [Description("TF自由放电时间")]
        [JsonProperty(PropertyName = "TFTime")]
        public short TFTime { get; set; } = 100;
        /// <summary>
        /// TL
        /// </summary>
        [Description("TL")]
        [JsonProperty(PropertyName = "TL")]
        public short TL { get; set; } = 0;
        /// <summary>
        /// TH
        /// </summary>
        [Description("TH")]
        [JsonProperty(PropertyName = "TH")]
        public short TH { get; set; } = 0;
        /// <summary>
        /// RT
        /// </summary>
        [Description("RT")]
        [JsonProperty(PropertyName = "RT")]
        public short RT { get; set; } = 1;
        /// <summary>
        /// R
        /// </summary>
        [Description("R")]
        [JsonProperty(PropertyName = "R")]
        public short R { get; set; } = 200;
        private static object LOCK_OBJ = new object();
        private static RJ6902GXSetting instance = null;
        /// <summary>
        /// 实例对象
        /// </summary>
        /// <param name="reload"></param>
        /// <returns></returns>
        public static RJ6902GXSetting Instance(bool reload = false)
        {
            if (reload || instance == null)
            {
                instance = CommonHelper.GetJsonFromFile<RJ6902GXSetting>(CONFIG_FILE_PATH, new RJ6902GXSetting());
            }
            return instance;
        }
        /// <summary>
        /// 保存
        /// </summary>
        public void Save()
        {
            lock (LOCK_OBJ)
            {
                CommonHelper.SaveToJsonFile(instance, CONFIG_FILE_PATH);
                instance = CommonHelper.GetJsonFromFile<RJ6902GXSetting>(CONFIG_FILE_PATH, new RJ6902GXSetting());
            }
        }
        /// <summary>
        /// 格式转换
        /// </summary>
        /// <returns></returns>
        public StructRJSettingParameter ToStructRJSettingParameter()
        {
            StructRJSettingParameter p = new StructRJSettingParameter();
            p.No = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.No).Reverse().ToArray() : BitConverter.GetBytes(this.No);
            p.Nanme = ASCIIEncoding.ASCII.GetBytes(this.Name);
            p.Voltage = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.ChargeVoltage).Reverse().ToArray() : BitConverter.GetBytes(this.ChargeVoltage);
            p.TKTime = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.TKTime).Reverse().ToArray() : BitConverter.GetBytes(this.TKTime);
            p.TFTime = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.TFTime).Reverse().ToArray() : BitConverter.GetBytes(this.TFTime);
            p.Vd1 = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.Vd1 * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.Vd1 * 10));
            p.Vd2 = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.Vd2 * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.Vd2 * 10));
            p.Vd3 = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.Vd3 * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.Vd3 * 10));
            p.TL = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.TL * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.TL * 10));
            p.TH = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.TH * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.TH * 10));
            p.RT = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.RT * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.RT * 10));
            p.R = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.R).Reverse().ToArray() : BitConverter.GetBytes(this.R);
            return p;
        }
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// RJ6902RCA配置信息
    /// </summary>
    public class RJ6902RCASetting
    {
        private static string CONFIG_FILE_PATH = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "RJ6902RCASettings.json");
        /// <summary>
        /// 备注
        /// </summary>
        [Description("Remark")]
        [JsonProperty(PropertyName = "Remark")]
        public string Remark { get; set; } = "";
        /// <summary>
        /// 编号
        /// </summary>
        [Description("编号")]
        [JsonProperty(PropertyName = "No")]
        public short No { get; set; } = 16;
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [JsonProperty(PropertyName = "Name")]
        public string Name { get; set; } = "ABCDEFGH";
        /// <summary>
        /// 电压
        /// </summary>
        [Description("电压")]
        [JsonProperty(PropertyName = "ChargeVoltage")]
        public short ChargeVoltage { get; set; } = 200;
        /// <summary>
        /// TK
        /// </summary>
        [Description("TK")]
        [JsonProperty(PropertyName = "TKTime")]
        public short TKTime { get; set; } = 100;
        /// <summary>
        /// TF
        /// </summary>
        [Description("TF")]
        [JsonProperty(PropertyName = "TFTime")]
        public short TFTime { get; set; } = 100;
        /// <summary>
        /// Vd1 百分部分，比如要设定 10% 则取值 100
        /// </summary>
        [Description("Vd1")]
        [JsonProperty(PropertyName = "Vd1")]
        public short Vd1 { get; set; } = 10;
        /// <summary>
        /// Vd2 百分部分，比如要设定 20% 则取值 200
        /// </summary>
        [Description("Vd2")]
        [JsonProperty(PropertyName = "Vd2")]
        public short Vd2 { get; set; } = 10;
        /// <summary>
        /// Vd3 百分部分，比如要设定 20% 则取值 200
        /// </summary>
        [Description("Vd3")]
        [JsonProperty(PropertyName = "Vd3")]
        public short Vd3 { get; set; } = 10;
        /// <summary>
        /// TL
        /// </summary>
        [Description("TL")]
        [JsonProperty(PropertyName = "TL")]
        public short TL { get; set; } = 0;
        /// <summary>
        /// TH
        /// </summary>
        [Description("TH")]
        [JsonProperty(PropertyName = "TH")]
        public short TH { get; set; } = 0;
        /// <summary>
        /// RT 带一位小数，也就是该值需要把设定值乘以 10
        /// </summary>
        [Description("RT")]
        [JsonProperty(PropertyName = "RT")]
        public float RT { get; set; } = 1.0f;
        /// <summary>
        /// R 电阻下限值
        /// </summary>
        [Description("R")]
        [JsonProperty(PropertyName = "R")]
        public short R { get; set; } = 200;
        /// <summary>
        /// CapMin 电容下限值 nF
        /// </summary>
        [Description("CapMin")]
        [JsonProperty(PropertyName = "CapMin")]
        public short CapMin { get; set; } = 0;
        /// <summary>
        /// CapMax 电容上限值 nF
        /// </summary>
        [Description("CapMax")]
        [JsonProperty(PropertyName = "CapMax")]
        public short CapMax { get; set; } = 0;
        /// <summary>
        /// 获取配置信息
        /// </summary>
        /// <returns></returns>
        public static List<RJ6902RCASetting> GetRJ6902RCASettings()
        {
            return CommonHelper.GetJsonListFromFile<RJ6902RCASetting>(CONFIG_FILE_PATH);
        }
        /// <summary>
        /// 保存配置信息
        /// </summary>
        /// <param name="list"></param>
        public static void SaveRJ6902RCASettings(List<RJ6902RCASetting> list)
        {
            CommonHelper.SaveToJsonFile(list, CONFIG_FILE_PATH);
        }
        /// <summary>
        /// 格式转换
        /// </summary>
        /// <returns></returns>
        public StructRJ6902RCASettingParameter ToStructRJ6902RCASettingParameter()
        {
            StructRJ6902RCASettingParameter p = new StructRJ6902RCASettingParameter();
            p.No = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.No).Reverse().ToArray() : BitConverter.GetBytes(this.No);
            p.Nanme = ASCIIEncoding.ASCII.GetBytes(this.Name);
            p.Voltage = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.ChargeVoltage).Reverse().ToArray() : BitConverter.GetBytes(this.ChargeVoltage);
            p.TKTime = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.TKTime).Reverse().ToArray() : BitConverter.GetBytes(this.TKTime);
            p.TFTime = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.TFTime).Reverse().ToArray() : BitConverter.GetBytes(this.TFTime);
            p.Vd1 = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.Vd1 * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.Vd1 * 10));
            p.Vd2 = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.Vd2 * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.Vd2 * 10));
            p.Vd3 = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.Vd3 * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.Vd3 * 10));
            p.TL = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.TL * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.TL * 10));
            p.TH = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.TH * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.TH * 10));
            p.RT = BitConverter.IsLittleEndian ? BitConverter.GetBytes((short)(this.RT * 10)).Reverse().ToArray() : BitConverter.GetBytes((short)(this.RT * 10));
            p.R = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.R).Reverse().ToArray() : BitConverter.GetBytes(this.R);
            p.CapMin = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.CapMin).Reverse().ToArray() : BitConverter.GetBytes(this.CapMin);
            p.CapMax = BitConverter.IsLittleEndian ? BitConverter.GetBytes(this.CapMax).Reverse().ToArray() : BitConverter.GetBytes(this.CapMax);
            return p;
        }
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// 测试判定数据、结果（查询类别中的 0x5B 命令返回结构）
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct StructRJTestJudgeResultData
    {
        /// <summary>
        /// Vd1
        /// </summary>
        [Description("Vd1")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd1;
        /// <summary>
        /// Vd2
        /// </summary>
        [Description("Vd2")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd2;
        /// <summary>
        /// Vd3
        /// </summary>
        [Description("Vd3")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd3;
        /// <summary>
        /// Vp
        /// </summary>
        [Description("Vp")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vp;
        /// <summary>
        /// Upt
        /// </summary>
        [Description("Upt")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2), Division(DivValue = 100.00f)]
        public byte[] UpTime;
        /// <summary>
        /// Rtd
        /// </summary>
        [Description("Rtd"), Division(DivValue = 10.00f, FormatValue = "F1")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] ResistanceData;
        /// <summary>
        /// 电容测试数据
        /// </summary>
        [Description("R1")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Reserve;
        /// <summary>
        /// Oc
        /// </summary>
        [Description("Oc")]
        public byte OpenCircuit;
        /// <summary>
        /// Sc
        /// </summary>
        [Description("Sc")]
        public byte ShortCircuit;
        /// <summary>
        /// Uv
        /// </summary>
        [Description("Uv")]
        public byte UnderVoltage;
        /// <summary>
        /// Ov
        /// </summary>
        [Description("Ov")]
        public byte OverVoltage;
        /// <summary>
        /// Drop1
        /// </summary>
        [Description("Drop1")]
        public byte Drop1;
        /// <summary>
        /// Drop2
        /// </summary>
        [Description("Drop2")]
        public byte Drop2;
        /// <summary>
        /// Drop3
        /// </summary>
        [Description("Drop3")]
        public byte Drop3;
        /// <summary>
        /// TL
        /// </summary>
        [Description("TL")]
        public byte TL;
        /// <summary>
        /// TH
        /// </summary>
        [Description("TH")]
        public byte TH;
        /// <summary>
        /// Rtr
        /// </summary>
        [Description("Rtr")]
        public byte ResistanceResult;
        /// <summary>
        /// 电容判定结果
        /// </summary>
        [Description("R2")]
        public byte ReserveForCapacitor;
        /// <summary>
        /// Result
        /// </summary>
        [Description("Result")]
        public byte Result;
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            //Vd1:D2100.00;Vd2:D2100.01;Vd3:D2100.02;Vp:D2100.03;Upt:D2100.04;Rtd:D2100.05;R1:D2100.06;Oc:D2100.07;Sc:D2100.08;Uv:D2100.09;Ov:D2100.10;Drop1:D2100.11;Drop2:D2100.12;Drop3:D2100.13;TL:D2100.14;TH:D2100.15;Rtr:D2100.16;R2:D2100.17;Result:D2100.18
            return CommonHelper.GetStructString(this);
        }
        /// <summary>
        /// 是否合格
        /// </summary>
        /// <returns></returns>
        public bool IsPass()
        {
            return Result == 0x01;
        }
    }
    /// <summary>
    /// 测试判定数据、结果（查询类别中的 0x6B 命令返回结构）
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct StructRJWaveData
    {
        /// <summary>
        /// 编号
        /// </summary>
        [Description("编号")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] No;
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Name;
        /// <summary>
        /// 设置电压
        /// </summary>
        [Description("设置电压")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Voltage;
        /// <summary>
        /// TK
        /// </summary>
        [Description("TK")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TK;
        /// <summary>
        /// TF
        /// </summary>
        [Description("TF")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TF;
        /// <summary>
        /// Vd1 Setting
        /// </summary>
        [Description("Vd1 Setting")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd1Setting;
        /// <summary>
        /// Vd2 Setting
        /// </summary>
        [Description("Vd2 Setting")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd2Setting;
        /// <summary>
        /// Vd3 Setting
        /// </summary>
        [Description("Vd3 Setting")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd3Setting;
        /// <summary>
        /// TL Setting
        /// </summary>
        [Description("TL Setting")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TLSetting;
        /// <summary>
        /// TH Setting
        /// </summary>
        [Description("TH Setting")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] THSetting;
        /// <summary>
        /// 标准波形的电阻测试时间
        /// </summary>
        [Description("标准波形的电阻测试时间")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] ResistanceTime;
        /// <summary>
        /// 标准波形的下限电阻
        /// </summary>
        [Description("标准波形的下限电阻")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] ResistanceLowerLimit;
        /// <summary>
        /// 预留无实际意义
        /// </summary>
        [Description("预留无实际意义")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] Reserve1;
        /// <summary>
        /// Tscale
        /// </summary>
        [Description("Tscale")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Tscale;
        /// <summary>
        /// Vd1
        /// </summary>
        [Description("Vd1")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd1;
        /// <summary>
        /// Vd2
        /// </summary>
        [Description("Vd2")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd2;
        /// <summary>
        /// Vd3
        /// </summary>
        [Description("Vd3")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd3;
        /// <summary>
        /// Vp
        /// </summary>
        [Description("Vp")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vp;
        /// <summary>
        /// TP
        /// </summary>
        [Description("TP")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TP;
        /// <summary>
        /// 标准波形电阻值，包含一位小数
        /// </summary>
        [Description("标准波形电阻值，包含一位小数")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] ResistanceData;
        /// <summary>
        /// 预留
        /// </summary>
        [Description("预留")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Reserve2;
    }
    /// <summary>
    /// 设置参数结构体（设置类别中的 0xFC 命令传入的参数）
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct StructRJSettingParameter
    {
        /// <summary>
        /// 编号
        /// </summary>
        [Description("编号")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] No;
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Nanme;
        /// <summary>
        /// 电压
        /// </summary>
        [Description("电压")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Voltage;
        /// <summary>
        /// TK时间
        /// </summary>
        [Description("TK时间")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TKTime;
        /// <summary>
        /// TF时间
        /// </summary>
        [Description("TF时间")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TFTime;
        /// <summary>
        /// Vd1
        /// </summary>
        [Description("Vd1")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd1;
        /// <summary>
        /// Vd2
        /// </summary>
        [Description("Vd2")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd2;
        /// <summary>
        /// Vd3
        /// </summary>
        [Description("Vd3")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd3;
        /// <summary>
        /// TL
        /// </summary>
        [Description("TL")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TL;
        /// <summary>
        /// TH
        /// </summary>
        [Description("TH")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TH;
        /// <summary>
        /// RT
        /// </summary>
        [Description("RT")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] RT;
        /// <summary>
        /// R
        /// </summary>
        [Description("R")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] R;
    }
    /// <summary>
    /// 设置参数结构体（设置类别中的 0xFC 命令传入的参数）
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct StructRJ6902RCASettingParameter
    {
        /// <summary>
        /// 编号
        /// </summary>
        [Description("编号")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] No;
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Nanme;
        /// <summary>
        /// 电压
        /// </summary>
        [Description("电压")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Voltage;
        /// <summary>
        /// TK时间
        /// </summary>
        [Description("TK时间")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TKTime;
        /// <summary>
        /// TF时间
        /// </summary>
        [Description("TF时间")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TFTime;
        /// <summary>
        /// Vd1
        /// </summary>
        [Description("Vd1")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd1;
        /// <summary>
        /// Vd2
        /// </summary>
        [Description("Vd2")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd2;
        /// <summary>
        /// Vd3
        /// </summary>
        [Description("Vd3")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Vd3;
        /// <summary>
        /// TL
        /// </summary>
        [Description("TL")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TL;
        /// <summary>
        /// TH
        /// </summary>
        [Description("TH")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] TH;
        /// <summary>
        /// RT
        /// </summary>
        [Description("RT")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] RT;
        /// <summary>
        /// R
        /// </summary>
        [Description("R")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] R;
        /// <summary>
        /// CapMin
        /// </summary>
        [Description("CapMin")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] CapMin;
        /// <summary>
        /// CapMax
        /// </summary>
        [Description("CapMax")]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] CapMax;
    }
    /// <summary>
    /// RJ6902基础参数类
    /// </summary>
    public class BaseRJ6902GXParam
    {
        /// <summary>
        /// 名称
        /// </summary>
        [Description("名称")]
        [JsonProperty(PropertyName = "remark")]
        public string Remark { get; set; } = "";
        /// <summary>
        /// 触发地址
        /// </summary>
        [Description("触发地址")]
        [JsonProperty(PropertyName = "triggerAddress")]
        public string TriggerAddress { get; set; } = "";
        /// <summary>
        /// Vd1结果地址
        /// </summary>
        [Description("Vd1结果地址")]
        [JsonProperty(PropertyName = "Vd1Address")]
        public string Vd1Address { get; set; } = "";
        /// <summary>
        /// Vd2结果地址
        /// </summary>
        [Description("Vd2结果地址")]
        [JsonProperty(PropertyName = "Vd2Address")]
        public string Vd2Address { get; set; } = "";
        /// <summary>
        /// Vd3结果地址
        /// </summary>
        [Description("Vd3结果地址")]
        [JsonProperty(PropertyName = "Vd3Address")]
        public string Vd3Address { get; set; } = "";
        /// <summary>
        /// Vp结果地址
        /// </summary>
        [Description("Vp结果地址")]
        [JsonProperty(PropertyName = "VpAddress")]
        public string VpAddress { get; set; } = "";
        /// <summary>
        /// Upt结果地址
        /// </summary>
        [Description("Upt结果地址")]
        [JsonProperty(PropertyName = "UptAddress")]
        public string UptAddress { get; set; } = "";
        /// <summary>
        /// Rtd结果地址
        /// </summary>
        [Description("Rtd结果地址")]
        [JsonProperty(PropertyName = "RtdAddress")]
        public string RtdAddress { get; set; } = "";
        /// <summary>
        /// 电容测试数据
        /// </summary>
        [Description("电容测试数据")]
        [JsonProperty(PropertyName = "CapDataAddress")]
        public string CapDataAddress { get; set; } = "";
        /// <summary>
        /// Oc结果地址
        /// </summary>
        [Description("Oc结果地址")]
        [JsonProperty(PropertyName = "OcAddress")]
        public string OcAddress { get; set; } = "";
        /// <summary>
        /// Sc结果地址
        /// </summary>
        [Description("Sc结果地址")]
        [JsonProperty(PropertyName = "ScAddress")]
        public string ScAddress { get; set; } = "";
        /// <summary>
        /// Uv结果地址
        /// </summary>
        [Description("Uv结果地址")]
        [JsonProperty(PropertyName = "UvAddress")]
        public string UvAddress { get; set; } = "";
        /// <summary>
        /// Ov结果地址
        /// </summary>
        [Description("Ov结果地址")]
        [JsonProperty(PropertyName = "OvAddress")]
        public string OvAddress { get; set; } = "";
        /// <summary>
        /// Drop1结果地址
        /// </summary>
        [Description("Drop1结果地址")]
        [JsonProperty(PropertyName = "Drop1Address")]
        public string Drop1Address { get; set; } = "";
        /// <summary>
        /// Drop2结果地址
        /// </summary>
        [Description("Drop2结果地址")]
        [JsonProperty(PropertyName = "Drop2Address")]
        public string Drop2Address { get; set; } = "";
        /// <summary>
        /// Drop3结果地址
        /// </summary>
        [Description("Drop3结果地址")]
        [JsonProperty(PropertyName = "Drop3Address")]
        public string Drop3Address { get; set; } = "";
        /// <summary>
        /// TL结果地址
        /// </summary>
        [Description("TL结果地址")]
        [JsonProperty(PropertyName = "TLAddress")]
        public string TLAddress { get; set; } = "";
        /// <summary>
        /// TH结果地址
        /// </summary>
        [Description("TH结果地址")]
        [JsonProperty(PropertyName = "THAddress")]
        public string THAddress { get; set; } = "";
        /// <summary>
        /// 电阻测试结果
        /// </summary>
        [Description("电阻测试结果")]
        [JsonProperty(PropertyName = "RtrAddress")]
        public string RtrAddress { get; set; } = "";
        /// <summary>
        /// 电容判定结果
        /// </summary>
        [Description("电容判定结果")]
        [JsonProperty(PropertyName = "CapAddress")]
        public string CapResultAddress { get; set; } = "";
        /// <summary>
        /// 总结果地址
        /// </summary>
        [Description("总结果地址")]
        [JsonProperty(PropertyName = "ResultAddress")]
        public string ResultAddress { get; set; } = "";
        /// <summary>
        /// 结果完成地址
        /// </summary>
        [Description("结果完成地址")]
        [JsonProperty(PropertyName = "testDoneAddress")]
        public string TestDoneAddress { get; set; } = "";
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// 测试仪串口配置
    /// </summary>
    public class RJ6902GXComParam : ComParameter
    {
        /// <summary>
        /// 从机地址
        /// </summary>
        [Description("从机地址")]
        [JsonProperty(PropertyName = "machineAddress")]
        public short MachineAddress { get; set; } = 2;
        /// <summary>
        /// PLC地址信息
        /// </summary>
        [Description("PLC地址信息")]
        [JsonProperty(PropertyName = "addressParameters")]
        public List<BaseRJ6902GXParam> AddressParameters { get; set; } = new List<BaseRJ6902GXParam>();
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// 测试仪TCP配置
    /// </summary>
    public class RJ6902GXTCPParam : TcpParameter
    {
        /// <summary>
        /// 从机地址
        /// </summary>
        [Description("从机地址")]
        [JsonProperty(PropertyName = "machineAddress")]
        public short MachineAddress { get; set; } = 2;
        /// <summary>
        /// PLC地址信息
        /// </summary>
        [Description("PLC地址信息")]
        [JsonProperty(PropertyName = "addressParameters")]
        public List<BaseRJ6902GXParam> AddressParameters { get; set; } = new List<BaseRJ6902GXParam>();
        /// <summary>
        /// 描述信息
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return CommonHelper.GetObjectString(this);
        }
    }
    /// <summary>
    /// Hi-Pot RJ6902系列操作类
    /// </summary>
    public class RJ6902Helper : BaseHelper
    {
        /// <summary>
        /// TCP配置文件
        /// </summary>
        static string rj6902gxTcpConfigPath = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "RJ6902GXTcpConfig.json");
        /// <summary>
        /// 串口配置文件
        /// </summary>
        static string rj6902gxComConfigPath = Path.Combine(CommonHelper.COMMON_CONFIG_DIR, "RJ6902GXComConfig.json");
        /// <summary>
        /// 获取TCP配置，返回List对象
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static List<RJ6902GXTCPParam> GetRJ6902TcpConfig()
        {
            return CommonHelper.GetJsonListFromFile<RJ6902GXTCPParam>(rj6902gxTcpConfigPath);
        }
        /// <summary>
        /// 保存配置信息（TCP）
        /// </summary>
        /// <param name="list"></param>
        /// <exception cref="Exception"></exception>
        public static void SaveRJ6902TcpConfig(List<RJ6902GXTCPParam> list)
        {
            CommonHelper.SaveToJsonFile(list, rj6902gxTcpConfigPath);
        }
        /// <summary>
        /// 获取配置信息（串口）
        /// </summary>
        /// <returns></returns>
        public static List<RJ6902GXComParam> GetRJ6902ComConfig()
        {
            return CommonHelper.GetJsonListFromFile<RJ6902GXComParam>(rj6902gxComConfigPath);
        }
        /// <summary>
        /// 保存配置信息（串口）
        /// </summary>
        /// <param name="list"></param>
        /// <exception cref="Exception"></exception>
        public static void SaveRJ6902ComConfig(List<RJ6902GXComParam> list)
        {
            CommonHelper.SaveToJsonFile(list, rj6902gxComConfigPath);
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        public RJ6902Helper()
        {
        }
        #region 每个Helper特定的参数
        /// <summary>
        /// 通讯超时时间，默认1000毫秒
        /// </summary>
        public override int CommunicationTimeout => BusinessConfig.Instance().HeliumTimeout;
        /// <summary>
        /// 延时查询，默认500ms
        /// </summary>
        public int QueryDelayTimes => BusinessConfig.Instance().RJDelayQueryTimes;
        /// <summary>
        /// 返回主界面
        /// </summary>
        public static readonly byte HOME = 0x00;
        /// <summary>
        /// 进入波形采集界面
        /// </summary>
        public static readonly byte ENTER_COLLECTION = 0xE1;
        /// <summary>
        /// 启动测试
        /// </summary>
        public static readonly byte CONTROL_CATEGORY = 0x0F;
        /// <summary>
        /// 设置类
        /// </summary>
        public static readonly byte SETTING_CATEGORY = 0x5A;
        /// <summary>
        /// 设置采集波形参数
        /// </summary>
        public static readonly byte SET_PARAMETERS = 0xFC;
        /// <summary>
        /// 调入标准波形
        /// </summary>
        public static readonly byte CALL_IN_WAVE = 0x01;
        /// <summary>
        /// 查询类
        /// </summary>
        public static readonly byte QUERY_CATEGORY = 0xF0;
        /// <summary>
        /// 启动测试
        /// </summary>
        public static readonly byte START_TEST = 0xFF;
        /// <summary>
        /// 查询测试判定数据、结果
        /// </summary>
        public static readonly byte TEST_DATA_RESULT = 0x5B;
        /// <summary>
        /// 查询标准波形信息
        /// </summary>
        public static readonly byte QUERY_STANDARD_WAVE = 0x6B;
        /// <summary>
        /// 帧头
        /// </summary>
        public static readonly byte START_FRAME = 0x7B;
        /// <summary>
        /// 帧尾
        /// </summary>
        public static readonly byte END_FRAME = 0x7D;
        /// <summary>
        /// 采集界面下启动采集命令
        /// </summary>
        public static readonly byte TEST_IN_COLLECT = 0xE2;
        /// <summary>
        /// 保存采集波形
        /// </summary>
        public static readonly byte SAVE_IN_COLLECT = 0xE3;
        /// <summary>
        /// 从机地址
        /// </summary>
        public byte MachineAddress { get; set; } = 0x02;
        #endregion
        /// <summary>
        /// 设定参数命令（RJ6902RCA)
        /// </summary>
        /// <param name="p"></param>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetRCASetParametersCommand(StructRJ6902RCASettingParameter p, byte machineAddress = 0x02)
        {
            byte[] array = CommonHelper.StructToBytes(p);
            List<byte> list = new List<byte>();
            list.AddRange(new byte[] {
                START_FRAME,
                0x00,
                0x2A,
                machineAddress,
                SETTING_CATEGORY,
                SET_PARAMETERS}
            );
            list.AddRange(array);
            list.Add(0xA4);
            list.Add(END_FRAME);
            byte[] result = list.ToArray();
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 设定参数命令（RJ6902GX)
        /// </summary>
        /// <param name="p"></param>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetSetParametersCommand(StructRJSettingParameter p, byte machineAddress = 0x02)
        {
            byte[] array = CommonHelper.StructToBytes(p);
            List<byte> list = new List<byte>();
            list.AddRange(new byte[] {
                START_FRAME,
                0x00,
                0x26,
                machineAddress,
                SETTING_CATEGORY,
                SET_PARAMETERS}
            );
            list.AddRange(array);
            list.Add(0xA4);
            list.Add(END_FRAME);
            byte[] result = list.ToArray();
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 返回主页命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetReturnHomeCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, CONTROL_CATEGORY, HOME, 0x19, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 进入采集界面命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetEnterCollectionCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, CONTROL_CATEGORY, ENTER_COLLECTION, 0xFA, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 调入标准波形命令
        /// </summary>
        /// <param name="no"></param>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetCallWaveNo(short no, byte machineAddress = 0x02)
        {
            byte[] wave = BitConverter.IsLittleEndian ? BitConverter.GetBytes(no).Reverse().ToArray() : BitConverter.GetBytes(no);
            byte[] result = new byte[] { START_FRAME, 0x00, 0x0A, machineAddress, SETTING_CATEGORY, CALL_IN_WAVE, wave[0], wave[1], 0x69, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 启动测试命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetStartTestCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, CONTROL_CATEGORY, START_TEST, 0x18, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 采集界面中启动采集命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetTestInCollectCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, CONTROL_CATEGORY, TEST_IN_COLLECT, 0x18, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 保存采集命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetSaveInCollectCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, CONTROL_CATEGORY, SAVE_IN_COLLECT, 0x18, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 查询判定结果命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetQueryJudgeCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, QUERY_CATEGORY, TEST_DATA_RESULT, 0x55, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 查询标准波形命令
        /// </summary>
        /// <param name="machineAddress"></param>
        /// <returns></returns>
        public static byte[] GetQueryStandardCommand(byte machineAddress = 0x02)
        {
            byte[] result = new byte[] { START_FRAME, 0x00, 0x08, machineAddress, QUERY_CATEGORY, QUERY_STANDARD_WAVE, 0x55, END_FRAME };
            result[result.Length - 2] = GetParityValue(result);
            return result;
        }
        /// <summary>
        /// 获取校验码
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public static byte GetParityValue(byte[] command)
        {
            byte result = 0x00;
            if (command != null && command.Length >= 4)
            {
                short total = 0;
                for (int i = 1; i < command.Length - 2; i++)
                {
                    total += command[i];
                }
                byte[] buffer = BitConverter.GetBytes(total);
                result = BitConverter.IsLittleEndian ? buffer[0] : buffer[1];
            }
            return result;
        }
        /// <summary>
        /// 是否正确数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private bool IsCorrectData(byte[] data)
        {
            return data != null && data.Length > 4 && data[4] != 0x99;
        }
        /// <summary>
        /// 获取错误信息
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private string GetErrorString(byte[] data)
        {
            string result = "超时";
            if (data != null && data.Length > 4 && data[4] == 0x99
                && data[0] == START_FRAME && data[data.Length - 1] == END_FRAME)
            {
                byte error = data[data.Length - 2];
                switch (error)
                {
                    case 0x01: result = "校验和错误"; break;
                    case 0x02: result = "命令类型错误"; break;
                    case 0x03: result = "命令字错误"; break;
                    case 0x04: result = "状态不符"; break;
                    case 0x05: result = "参数错误"; break;
                }
            }
            return result;
        }
        /// <summary>
        /// 启动测试
        /// </summary>
        /// <returns></returns>
        public string GetStartTest()
        {
            string result = "超时";
            byte[] buffer = this.CommunicationType == ECommunicationType.TCP ?
                this.GetTcp(GetStartTestCommand(this.MachineAddress))
                : this.GetCom(GetStartTestCommand(this.MachineAddress));
            if (buffer != null)
            {
                result = string.Join(" ", buffer.Select(v => v.ToString("X2")));
            }
            return result;
        }
        /// <summary>
        /// 进入采集界面
        /// </summary>
        /// <returns></returns>
        public string GetEnterCollection()
        {
            string result = "超时";
            byte[] buffer = this.CommunicationType == ECommunicationType.TCP ?
                this.GetTcp(GetEnterCollectionCommand(this.MachineAddress))
                : this.GetCom(GetEnterCollectionCommand(this.MachineAddress));
            if (buffer != null)
            {
                result = string.Join(" ", buffer.Select(v => v.ToString("X2")));
            }
            return result;
        }
        /// <summary>
        /// 设置参数
        /// </summary>
        /// <returns></returns>
        public string GetSetParameters(object p)
        {
            string result = "超时";
            byte[] buffer = this.CommunicationType == ECommunicationType.TCP ?
                (p is StructRJSettingParameter ? this.GetTcp(GetSetParametersCommand((StructRJSettingParameter)p, this.MachineAddress)) : this.GetTcp(GetRCASetParametersCommand((StructRJ6902RCASettingParameter)p, this.MachineAddress)))
                : (p is StructRJSettingParameter ? this.GetCom(GetSetParametersCommand((StructRJSettingParameter)p, this.MachineAddress)) : this.GetCom(GetRCASetParametersCommand((StructRJ6902RCASettingParameter)p, this.MachineAddress)));
            if (buffer != null)
            {
                result = string.Join(" ", buffer.Select(v => v.ToString("X2")));
            }
            return result;
        }
        /// <summary>
        /// 返回主界面
        /// </summary>
        /// <returns></returns>
        public string GetReturnHome()
        {
            string result = "超时";
            byte[] buffer = this.CommunicationType == ECommunicationType.TCP ?
                this.GetTcp(GetReturnHomeCommand(this.MachineAddress))
                : this.GetCom(GetReturnHomeCommand(this.MachineAddress));
            if (buffer != null)
            {
                result = string.Join(" ", buffer.Select(v => v.ToString("X2")));
            }
            return result;
        }
        private object READ_LOCK = new object();
        /// <summary>
        /// 串口通讯并返回结果
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private byte[] GetCom(byte[] cmd)
        {
            lock (READ_LOCK)
            {
                byte[] result = null;
                if (this.IsConnected)
                {
                    try
                    {
                        this.SerialSend(cmd);
                        result = this.GetReturnBuffer(true, START_FRAME, END_FRAME);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Error(ex);
                    }
                    finally
                    {
                        LogHelper.Info($"【{this.Name}】发送数据：【{(string.Join(" ", cmd.Select(v => v.ToString("X2"))))}】，接收数据：【{(result == null || result.Length == 0 ? "" : string.Join(" ", result.Select(v => v.ToString("X2"))))}】");
                    }
                }
                return result;
            }
        }
        /// <summary>
        /// TCP通讯并返回结果
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private byte[] GetTcp(byte[] cmd)
        {
            lock (READ_LOCK)
            {
                byte[] result = null;
                if (this.IsConnected)
                {
                    try
                    {
                        this.TcpSend(cmd);
                        result = this.TcpReceive();
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Error(ex);
                    }
                    finally
                    {
                        LogHelper.Info($"【{this.Name}】发送数据：【{(string.Join(" ", cmd.Select(v => v.ToString("X2"))))}】，接收数据：【{(result == null || result.Length == 0 ? "" : string.Join(" ", result.Select(v => v.ToString("X2"))))}】");
                    }
                }
                return result;
            }
        }
        /// <summary>
        /// 参数的数据处理
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="plcEntity"></param>
        /// <param name="isOK"></param>
        /// <param name="result"></param>
        private void BusinessQueryParameterHandler(byte[] buffer, RJ6902GXQueryParameterSetting plcEntity, ref bool isOK, ref string result)
        {
            var param = new RJ6902ExcuteEntity()
            {
                Data = buffer,
                IsOK = isOK,
                Result = result,
                QueryPLCEntity = plcEntity
            };
            param = CommonHelper.GetJson(PluginManager.Instance.Excute(this.Name, "RJ6902GX_PARAMETER", CommonHelper.GetJsonString(param, Formatting.None)), param);
            isOK = param.IsOK;
            result = param.Result;
        }
        /// <summary>
        /// 数据处理
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="plcEntity"></param>
        /// <param name="isOK"></param>
        /// <param name="result"></param>
        private void BusinessHandler(byte[] buffer, RJ6902PLCEntity plcEntity, ref bool isOK, ref string result)
        {
            var param = new RJ6902ExcuteEntity()
            {
                Data = buffer,
                IsOK = isOK,
                Result = result,
                PLCEntity = plcEntity
            };
            param = CommonHelper.GetJson(PluginManager.Instance.Excute(this.Name, "RJ6902GX_TEST", CommonHelper.GetJsonString(param, Formatting.None)), param);
            isOK = param.IsOK;
            result = param.Result;
        }
        /// <summary>
        /// 参数设定
        /// </summary>
        /// <param name="setting"></param>
        /// <returns></returns>
        public bool SetRJ6902Parameter(object setting)
        {
            bool isSuccess = true;
            Stopwatch stopwatch = Stopwatch.StartNew();
            string result = "超时";
            byte[] buffer = null;
            if (this.IsConnected)
            {
                this.RealShowMessage($"【{this.Name}】进行参数设定");
                try
                {
                    this.RealShowMessage($"【{this.Name}】进入采集界面");
                    buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetEnterCollectionCommand(this.MachineAddress)) : GetTcp(GetEnterCollectionCommand(this.MachineAddress));
                    if (this.IsCorrectData(buffer))
                    {
                        this.RealShowMessage($"【{this.Name}】设置参数");
                        //设置参数
                        byte[] parameterBuffer = setting is RJ6902RCASetting ?
                            GetRCASetParametersCommand(((RJ6902RCASetting)setting).ToStructRJ6902RCASettingParameter(), this.MachineAddress)
                            : GetSetParametersCommand(((RJ6902GXSetting)setting).ToStructRJSettingParameter(), this.MachineAddress);
                        buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(parameterBuffer) : GetTcp(parameterBuffer);
                        float rt = setting is RJ6902RCASetting ? ((RJ6902RCASetting)setting).RT : 0.0f;
                        if (this.IsCorrectData(buffer))
                        {
                            this.RealShowMessage($"【{this.Name}】启动采集");
                            //启动采集
                            buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetTestInCollectCommand(this.MachineAddress)) : GetTcp(GetTestInCollectCommand(this.MachineAddress));
                            if (this.IsCorrectData(buffer))
                            {
                                int sleepTimes = (int)(rt * 1000 + this.QueryDelayTimes);
                                this.RealShowMessage($"【{this.Name}】等待采集完成，预计 {sleepTimes} 毫秒");
                                Thread.Sleep(sleepTimes);
                                this.RealShowMessage($"【{this.Name}】保存采集");
                                //保存采集
                                buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetSaveInCollectCommand(this.MachineAddress)) : GetTcp(GetSaveInCollectCommand(this.MachineAddress));
                                if (this.IsCorrectData(buffer))
                                {
                                    isSuccess = true;
                                }
                                else
                                {
                                    isSuccess = false;
                                }
                            }
                            else
                            {
                                isSuccess = false;
                            }
                        }
                        else
                        {
                            isSuccess = false;
                        }
                    }
                    else
                    {
                        isSuccess = false;
                    }
                    if (isSuccess)
                    {
                        result = "OK";
                    }
                    else
                    {
                        result = this.GetErrorString(buffer);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                }
                finally
                {
                    Thread.Sleep(2);
                    this.RealShowMessage($"【{this.Name}】返回主界面");
                    buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetReturnHomeCommand(this.MachineAddress)) : GetTcp(GetReturnHomeCommand(this.MachineAddress));
                }
            }
            else
            {
                isSuccess = false;
            }
            stopwatch.Stop();
            this.RealShowMessage($"【{this.Name}】参数设定，耗时：{stopwatch.ElapsedMilliseconds} 毫秒，设定结果：{result}。", isSuccess);
            return isSuccess;
        }
        /// <summary>
        /// 测试仪业务逻辑
        /// </summary>
        /// <param name="handlerName"></param>
        /// <param name="handlerType"></param>
        /// <param name="otherAddress"></param>
        /// <param name="otherData"></param>
        public override void RealHandler(string handlerName, EHandlerType handlerType, object otherAddress, object otherData)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            string result = "超时";
            bool isSuccess = false;
            bool isOk = false;
            byte[] buffer = null;
            if (this.IsConnected)
            {
                try
                {
                    if (handlerType.Equals(EHandlerType.HiPot_RJ6902))
                    {
                        this.RealShowMessage($"【{this.Name}】{handlerName}");
                        if (otherData != null && (otherData is RJ6902RCASetting || otherData is RJ6902GXSetting))
                        {
                            short no = otherData is RJ6902RCASetting ? ((RJ6902RCASetting)otherData).No : ((RJ6902GXSetting)otherData).No;
                            LogHelper.Info($"【{this.Name}】调入标准波形");
                            buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetCallWaveNo(no, this.MachineAddress)) : GetTcp(GetCallWaveNo(no, this.MachineAddress));
                        }
                        this.RealShowMessage($"【{this.Name}】启动测试");
                        int sleepTimes = this.QueryDelayTimes;
                        if (otherData != null && otherData is RJ6902RCASetting)
                        {
                            sleepTimes = (int)(sleepTimes + ((RJ6902RCASetting)otherData).RT * 1000);
                        }
                        buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetStartTestCommand(this.MachineAddress)) : GetTcp(GetStartTestCommand(this.MachineAddress));
                        if (this.IsCorrectData(buffer))
                        {
                            this.RealShowMessage($"【{this.Name}】等待测试完成，预计 {sleepTimes} 毫秒");
                            Thread.Sleep(sleepTimes);
                            this.RealShowMessage($"【{this.Name}】查询测试结果");
                            buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetQueryJudgeCommand(this.MachineAddress)) : GetTcp(GetQueryJudgeCommand(this.MachineAddress));
                            if (this.IsCorrectData(buffer))
                            {
                                isSuccess = true;
                            }
                        }
                        else
                        {
                            result = this.GetErrorString(buffer);
                        }
                    }
                    else if (handlerType.Equals(EHandlerType.HiPot_RJ6902_Query_Parameters))
                    {
                        this.RealShowMessage($"【{this.Name}】{handlerName}");
                        buffer = this.CommunicationType == ECommunicationType.SERIAL ? GetCom(GetQueryStandardCommand(this.MachineAddress)) : GetTcp(GetQueryStandardCommand(this.MachineAddress));
                        if (this.IsCorrectData(buffer))
                        {
                            isSuccess = true;
                        }
                        else
                        {
                            result = this.GetErrorString(buffer);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex);
                }
                finally
                {
                    if (handlerType.Equals(EHandlerType.HiPot_RJ6902))
                    {
                        RJ6902PLCEntity entity1 = otherAddress as RJ6902PLCEntity;
                        BusinessHandler(buffer, entity1, ref isOk, ref result);
                        stopwatch.Stop();
                        this.RealShowMessage($"【{this.Name}】HiPot测试，耗时：{stopwatch.ElapsedMilliseconds} 毫秒，测试结果：{result}，是否合格：{(isOk ? "合格" : "不合格")}。", isSuccess && isOk);
                    }
                    else if (handlerType.Equals(EHandlerType.HiPot_RJ6902_Query_Parameters))
                    {
                        RJ6902GXQueryParameterSetting entity2 = otherAddress as RJ6902GXQueryParameterSetting;
                        BusinessQueryParameterHandler(buffer, entity2, ref isOk, ref result);
                        stopwatch.Stop();
                        this.RealShowMessage($"【{this.Name}】HiPot参数查询，耗时：{stopwatch.ElapsedMilliseconds} 毫秒，查询结果：{result}。", isSuccess && isOk);
                    }
                }
            }
            else
            {
                this.RealShowMessage($"【{this.Name}】设备未连接");
            }
        }
    }
}
